#include "GMap.h"


CMap::CMap(SOUND *sManager, int idWorld)
{
	if (idWorld==4)
		_loadGame=true;
	else
		_loadGame=false;
	_world=idWorld;
	_isGameOver=false;
	_soundManager=sManager;
	_quadTree=NULL;
	Object::_effect=new CEffect();
	CBackGround::InitResoure();
	CItem::InitResoure();
	CBonuses::InitResoure();
	CEnemy::InitResoure();
	_infomation=NULL;
	_myMario=NULL;
	LoadNewWorld();
	_bulletManager=new BulletManager(3,400);
	
	Object::info=_infomation;
}
CMap::~CMap()
{
	delete _quadTree;
	delete _myScreen;
}
void CMap::LoadNewWorld()
{
	char *filename=NULL;
	switch(_world)
	{
	case 0:
		filename="\Maps/MapMenu.map";					
		break;
	case 1:
		filename="\Maps/MapI.map";					
		break;
	case 2:
		filename="\Maps/MapII.map";	
		break;
	case 3:
		filename="\Maps/MapIII.map";	
		break;
	case 4:
		filename="\Maps/SaveGame.map";
	}
	if(filename!=NULL)
		LoadDataFromFile(filename);
}

void CMap::LoadDataFromFile(char* filePath)
{	
	ifstream f(filePath);
	vector<string> itemsInfo;
	if(f.is_open())
	{		
		string line;
		int id;
		int leftCamera;
		int kind;
		int left, top;
		int hidden;
		int level;
		int life;
		int coin;
		getline(f,line);	
		getline(f,line);
		itemsInfo = SplitString(line, ' ');
		_mapWidth=atoi(itemsInfo.at(0).c_str());
		_mapHeight=atoi(itemsInfo.at(1).c_str());
		_world=atoi(itemsInfo.at(2).c_str());
		leftCamera=atoi(itemsInfo.at(3).c_str());
		_quadTree=new QuadTree(_mapWidth,_mapHeight);
		_myScreen=new CScreen(leftCamera,0,_mapWidth,WINDOW_HEIGHT);
		getline(f,line);
		getline(f,line);
		itemsInfo = SplitString(line, ' ');
		level =atoi(itemsInfo.at(0).c_str());	
		left=atoi(itemsInfo.at(1).c_str());
		top=atoi(itemsInfo.at(2).c_str());
		life=atoi(itemsInfo.at(3).c_str());
		coin=atoi(itemsInfo.at(4).c_str());
		if (_infomation==NULL)
		{
			_infomation=new Infomation(life,coin,_world);
		}
		if (_myMario!=NULL&&_myMario->_level>=0)
		{
			level=_myMario->_level;
		}
			_myMario=new Mario(level,left,top,_myScreen,_quadTree,_soundManager);
			//_quadTree->Add(_quadTree->_pRoot,_myMario);
		while(1)
		{
			Object *Ob=NULL;
			getline(f,line);	
			itemsInfo = SplitString(line, ' ');
			if(strcmp(line.c_str(), "[End]") == 0)
				break;
			if(strcmp(itemsInfo.at(0).c_str(), "[Obj]") == 0)
				continue;
			id =atoi(itemsInfo.at(0).c_str());	
			kind=atoi(itemsInfo.at(1).c_str());
			left=atoi(itemsInfo.at(2).c_str());
			top=atoi(itemsInfo.at(3).c_str());
			hidden=atoi(itemsInfo.at(4).c_str());

			switch(id)
			{
			case 0://CItems
				if(kind==0)
					Ob=new CItem(left,top,kind,_world,_quadTree,_soundManager);
				else
					Ob=new CItem(left,top,kind,hidden,_quadTree,_soundManager);
				break;
			case 2://CEnemy
				Ob=new CEnemy(left,top,_myScreen,_quadTree,kind,_soundManager);
				break;
			case 3://CBonus
				Ob=new CBonuses(left,top,_quadTree,kind,_soundManager);
				break;
			}
			if(Ob!=NULL)
				_quadTree->Add(_quadTree->_pRoot,Ob);
		}
		CreateSightMap(_world);

	}
	f.close();
}

vector<string> CMap::SplitString(std::string str, char ch)
{
	vector<string> result;
	int n = str.size();
	string line = "";
	for(int i = 0; i < n; i++){
		while((i<n)&&(str.at(i)!=ch))
		{
			line.push_back(str.at(i));
			i++;
		}
		result.push_back(line);
		line.clear();		
	}
	return result;
}

void CMap::SaveDataToFile()	
{
	vector<Object*> result;
	int typeObj=0;
	int kind=0;
	int left=0;
	int top=0;
	int hidden=0;
	_quadTree->GetAllObj(_quadTree->_pRoot,result);
	ofstream ff("\Maps/SaveGame.map");
	if(ff.is_open())
	{
		ff<<"[Obj] [Size Game] [World] [Camera] [Mario]\n";
		ff<<_mapWidth; ff<<" "; ff<<_mapHeight; ff<<" ";
		ff<<_world; ff<<" "; ff<<_myScreen->Camera.left; ff<<" "; ff<<0; ff<<"\n";
		ff<<"[Obj] [Mario] [Lever] [Post] [Life] [Coin]\n";
		ff<<_myMario->_level; ff<<" ";
		ff<<_myMario->_pRECT->left; ff<<" "; ff<<_myMario->_pRECT->top; ff<<" ";
		 ff<<_infomation->Life-1;ff<<" ";ff<<_infomation->CointCounter;  ff<<"\n";
		for (int i=0;i<result.size();i++)
		{
			Object* obj= result[i];
			if (obj->_typeObj!=-1)
			{
				switch(typeObj)
				{
					case 0://CItems
						ff<<"[Obj] [CItems]\n";
						break;
					case 2://CEnemy
						ff<<"[Obj] [CEnemy]\n";
						break;
					case 3://CBonus
						ff<<"[Obj] [Bonus]\n";
						break;
					}
					typeObj=obj->_typeObj;
					kind=obj->_kind;
					left=obj->_pRECT->left;
					top=obj->_pRECT->top;
					hidden=obj->_hidden;
					ff<<typeObj;ff<<" ";
					ff<<kind;ff<<" ";
					ff<<left;ff<<" ";
					ff<<top;ff<<" ";
					ff<<hidden;ff<<"\n";
			}
		}
		ff<<"[End]";
	}	
	ff.close();
}

void CMap::Reset()
{
	_isGameOver=false;
	_bulletManager->Reset();
	_myScreen->Reset();
	LoadNewWorld();
}
void CMap::FinshMap()
{
	_bulletManager->Reset();
	_world++;
	if(_world>3)
		_world=1;
	_infomation->World=_world;
	LoadNewWorld();
	_myMario->_pSprite->_rootTime=GetTickCount();
	_myMario->_pRECT->left=7;_myMario->_pRECT->right=26;
	_myMario->_pSprite->_left=0;
	_myMario->_justChangeLevel=true;
	_myMario->_status=0;
	_myMario->_screen=_myScreen;
	_myMario->_quadTree=_quadTree;
}
void CMap::Update(DWORD tickPerFrame,CDxInput* input)
{
	_quadTree->UpdatePosition(_quadTree->_pRoot);
	if(_myMario!=NULL&&_myMario->_pRECT->top>WINDOW_HEIGHT)//mario is die
	{
		_infomation->Life--;
		if(_infomation->Life<1)
			_isGameOver=true;
		else
		{
			_myMario->_level=0;
			Reset();
		}
	}
	if(_infomation->time<0)
		_isGameOver=true;
	if(_myMario->_pRECT->right>=_myScreen->_limRight-50 &&_world!=0 )//finshMap
	{
		_soundManager->Play("FinishMap",false);
		FinshMap();
	}
		
	if(_myMario!=NULL&&_myMario->_status!=2)
	{
		if(input->OnKeyPress(DIK_Z))
			_myMario->SetVX(MARIO_HIGH_SPEED);
		if(input->OnKeyUp(DIK_Z))
			_myMario->SetVX(MARIO_NORMAL_SPEED);
		if(input->OnKeyPress(DIK_LEFT))
		{ 
			if(!_myMario->_pSprite->_enable)
			{
				if(_myMario->_status!=1)
				{
					_myMario->_pSprite->_enable=true;
				}
			}
			if(_myMario->_direction==Direction::Right)
			{
				_myMario->_direction=Direction::Letf;
				_myMario->ChangeDirectory(false);
			}
			_myMario->Move();
		}
		else 
			if (input->OnKeyPress(DIK_RIGHT))
			{
				if(!_myMario->_pSprite->_enable)
				{
					if(_myMario->_status!=1)
					{						
						_myMario->_pSprite->_enable=true;
					}
				}
				if(_myMario->_direction==Direction::Letf)
				{
					_myMario->_direction=Direction::Right;
					_myMario->ChangeDirectory(false);
				}
				_myMario->Move();
			}
		if(input->OnKeyDown(DIK_SPACE))
		{
			if(_myMario->_status!=1)//dont' jump
			{
				_soundManager->Play("Jump",false);
				_myMario->_status=1;
				_myMario->ChangeDirectory(true);
				_myMario->_isUpDown = true ;
				_myMario->_deltaY =12*tickPerFrame/10;
				_myMario->Set_Up(true);
				_myMario->_isSuper=false;
			}
		}
		if((input->OnKeyDown(DIK_Z)||input->OnKeyDown(DIK_UP)))
		{
			if(_myMario->_status==1&&_myMario->_isUpDown&&!_myMario->_isSuper)
			{
				_myMario->_isSuper=true;
			}
		}
		if(input->OnKeyDown(DIK_Z)&&_myMario->_level==2)
		{
			bool result=_bulletManager->AddBullet(_quadTree,_myMario->_direction,
				(_myMario->_direction==Direction::Letf?_myMario->_pRECT->left-25:_myMario->_pRECT->right+20),
				_myMario->_pRECT->top+20,_myScreen);
			if(result)			
				_soundManager->Play("Shoot",true);
		}
		if(input->OnKeyDown(DIK_DOWN)&&_world==0)
		{
			RECT r0;
			r0.left=_myMario->_pRECT->left;
			r0.top=_myMario->_pRECT->top;
			r0.right=_myMario->_pRECT->right;
			r0.bottom=_myMario->_pRECT->bottom;
			RECT r1;
			r1.left=330;r1.top=400;r1.right=360;r1.bottom=425;
			RECT r2;
			r2.left=505;r2.top=400;r2.right=535;r2.bottom=425;
			RECT r3;
			r3.left=680;r3.top=400;r3.right=710;r3.bottom=425;
			if(_quadTree->CheckRECTInRECT(r0,r1))
			{
				_world=3;
				Reset();
			}
			if(_quadTree->CheckRECTInRECT(r0,r2))
			{
				_world=2;
				Reset();
			}
			if(_quadTree->CheckRECTInRECT(r0,r3))
			{
				_world=1;
				Reset();
			}
		}
	}
}
void CMap::Draw()
{
	_quadTree->DrawObjects(_myScreen->Camera.left,_myScreen->Camera);
	Object::_effect->Draw(_myScreen->Camera.left);
	_myMario->Draw();
	_infomation->Draw();
	if(_isGameOver)
	{
		_infomation->DrawGameOver();
		
	}
}
void CMap::CreateSightMap(int world)
{
	switch (world)
	{
	case 0:
		if(_mapWidth>1000)
		{
			for (int i=0;i<_mapWidth-800;i+=400)//cloud
			{
				Object *obj1=NULL;
				Object *obj2=NULL;
				Object *obj3=NULL;
				Object *obj11=NULL;
				Object *obj22=NULL;
				int n=rand()&80;
				obj1=new CBackGround(i+n,20+n/2,0);
				obj2=new CBackGround(i+60+n,125+n/2,0);
				obj3=new CBackGround(i+180+n,90+n/2,0);
				if(obj1!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj1);
				if(obj2!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj2);
				if(obj3!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj3);
				obj11=new CBackGround(i+n*10,500,2);
				n=rand()&10;
				obj22=new CBackGround(i+n*70,500,2);
				if(obj11!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj11);
				if(obj22!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj22);
			}		

			Object *obj4=NULL;
			Object *obj5=NULL;
			Object *obj6=NULL;
			Object *obj7=NULL;
			Object *obj8=NULL;
			Object *obj9=NULL;
			Object *obj10=NULL;
			obj4=new CBackGround(100,400,7);//mountain
			obj5=new CBackGround(215,438,3);//tree
			obj6=new CBackGround(600,495,1);//fender
			obj7=new CBackGround(1000,442,7);//mountain
			obj8=new CBackGround(1200,400,7);//mountain
			obj9=new CBackGround(900,390,6);//cactus
			obj10=new CBackGround(1500,438,3);	
			if(obj4!=NULL)
				_quadTree->Add(_quadTree->_pRoot,obj4);
			if(obj5!=NULL)
				_quadTree->Add(_quadTree->_pRoot,obj5);
			if(obj6!=NULL)
				_quadTree->Add(_quadTree->_pRoot,obj6);
			if(obj7!=NULL)
				_quadTree->Add(_quadTree->_pRoot,obj7);
			if(obj8!=NULL)
				_quadTree->Add(_quadTree->_pRoot,obj8);
			if(obj9!=NULL)
				_quadTree->Add(_quadTree->_pRoot,obj9);
			if(obj10!=NULL)
				_quadTree->Add(_quadTree->_pRoot,obj10);
		}
		break;
	case 1:
		if(_mapWidth>1000)
		{
			for (int i=0;i<_mapWidth-800;i+=400)//cloud
			{
				Object *obj1=NULL;
				Object *obj2=NULL;
				Object *obj3=NULL;
				int n=rand()&80;
				obj1=new CBackGround(i+n,20+n/2,0);
				obj2=new CBackGround(i+60+n,125+n/2,0);
				obj3=new CBackGround(i+180+n,90+n/2,0);
				if(obj1!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj1);
				if(obj2!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj2);
				if(obj3!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj3);
			}		

			for (int i=0;i<_mapWidth-800;i+=1000)//mountain
			{
				Object *obj1=NULL;
				Object *obj2=NULL;
				int n=rand()&40;
				obj1=new CBackGround(i+n*2,442+n,7);
				if(obj1!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj1);
			}

			for (int i=0;i<_mapWidth-1000;i+=1200)//cactus
			{
				Object *obj1=NULL;
				int n=rand()&20;
				obj1=new CBackGround(i+n*50,390+n,6);
				if(obj1!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj1);
			}
			for (int i=0;i<_mapWidth-800;i+=1400)//fender
			{
				
				Object *obj1=NULL;
				int n=rand()&20;
				obj1=new CBackGround(i+n*10,495,1);
				if(obj1!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj1);
			}	
			for (int i=0;i<_mapWidth-1000;i+=600)//grass
			{

				Object *obj1=NULL;
				Object *obj2=NULL;
				int n=rand()&20;
				obj1=new CBackGround(i+n*10,500,2);
				n=rand()&10;
				obj2=new CBackGround(i+n*70,500,2);
				if(obj1!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj1);
				if(obj2!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj2);
			}	
			for (int i=0;i<_mapWidth-800;i+=1000)//big tree and small tree
			{

				Object *obj1=NULL;
				Object *obj2=NULL;
				int n=rand()&20;
				obj1=new CBackGround(i+n*5,438,3);
				n=rand()&30;
				obj2=new CBackGround(i+n*20,470,4);
				if(obj1!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj1);
				if(obj2!=NULL)
					_quadTree->Add(_quadTree->_pRoot,obj2);
			}	
			Object *obj1=NULL;
			Object *obj2=NULL;
			Object *obj3=NULL;
			obj1=new CBackGround(_mapWidth-100,242,8);
			obj2=new CBackGround(_mapWidth-31,242,9);
			obj3=new CBackGround(_mapWidth-250,497,5);
			if(obj1!=NULL)
				_quadTree->Add(_quadTree->_pRoot,obj1);
			if(obj2!=NULL)
				_quadTree->Add(_quadTree->_pRoot,obj2);
			if(obj3!=NULL)
				_quadTree->Add(_quadTree->_pRoot,obj3);
			
		}
		break;
	case 2:
		if(_mapWidth>1000)
		   {
			   for (int i=0;i<_mapWidth-800;i+=400)//cloud and star
			   {
				   Object *obj1=NULL;
				   Object *obj2=NULL;
				   Object *obj3=NULL;
				   Object *obj4=NULL;
				   Object *obj5=NULL;
				   int n=rand()&80;
				   obj1=new CBackGround(i+n,20+n/2,10);
				   obj2=new CBackGround(i+60+n,125+n/2,10);
				   n=rand()&50;
				   obj3=new CBackGround(i+180+n,90+n/2,16);
				   n=rand()&50;
				   obj4=new CBackGround(i+60+n,115+n/2,16);
				   n=rand()&50;
				   obj5=new CBackGround(i+180+n,95+n/2,16);
				   if(obj1!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj1);
				   if(obj2!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj2);
				   if(obj3!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj3);
				   if(obj4!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj4);
				   if(obj5!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj5);
			   }		

			   for (int i=0;i<_mapWidth-800;i+=1000)//mountain
			   {
				   Object *obj1=NULL;
				   Object *obj2=NULL;
				   int n=rand()&40;
				   obj1=new CBackGround(i+n*2,442+n,14);
				   if(obj1!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj1);
			   }

			   for (int i=0;i<_mapWidth-400;i+=250)//bush
			   {
				   Object *obj1=NULL;
				   obj1=new CBackGround(i,420,13);
				   if(obj1!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj1);
			   }
			   for (int i=0;i<_mapWidth-800;i+=1400)//fender
			   {

				   Object *obj1=NULL;
				   Object *obj2=NULL;
				   int n=rand()&20;
				   obj1=new CBackGround(i+n*10,495,1);
				   n=rand()&50+50;
				   obj2=new CBackGround(i+n*5,435,12);//lam
				   if(obj1!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj1);
				   if(obj2!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj2);
			   }	
			   for (int i=0;i<_mapWidth-1000;i+=600)//grass
			   {

				   Object *obj1=NULL;
				   Object *obj2=NULL;
				   int n=rand()&20;
				   obj1=new CBackGround(i+n*10,500,11);
				   n=rand()&10;
				   obj2=new CBackGround(i+n*70,500,11);
				   if(obj1!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj1);
				   if(obj2!=NULL)
					   _quadTree->Add(_quadTree->_pRoot,obj2);
			   }	
			
			   Object *obj1=NULL;
			   Object *obj2=NULL;
			   obj1=new CBackGround(_mapWidth-200,260,15);
			   obj2=new CBackGround(_mapWidth-250,497,5);
			   if(obj1!=NULL)
				   _quadTree->Add(_quadTree->_pRoot,obj1);
			   if(obj2!=NULL)
				   _quadTree->Add(_quadTree->_pRoot,obj2);
			   for (int i=0;i<_mapWidth;i+=70)
			   {
				   Object *obj=NULL;
				   obj=new CBackGround(i,530,18);
				   if (obj!=NULL)
				   {
					   _quadTree->Add(_quadTree->_pRoot,obj);
				   }
			   }
		   }
		   break;
	case 3:
		if (_mapWidth>1000)
		{
			for(int i=0;i<_mapHeight;i+=70)
				for (int j=0;j<_mapWidth;j+=70)
				{
					Object *obj=NULL;
					obj=new CBackGround(j,i,17);
					if (obj!=NULL)
					{
						_quadTree->Add(_quadTree->_pRoot,obj);
					}
				}
		}
		break;

	}

}